package logic

import (
	"bufio"
	"fmt"
	"gitee.com/hardykay/AnalysisLampLog/models"
	"os"
	"regexp"
	"strings"
	"sync"
	"time"
)

func Run(files []string) {
	var gx sync.WaitGroup
	gx.Add(4)
	var data = make(chan models.RunSql, 1000)
	for i := 0; i < 4; i++ {
		go insert(&gx, data)
	}

	size := 16
	for i := 0; i < len(files); i += size {
		l := i + size
		if l > len(files) {
			l = len(files)
		}
		read(files[i:l], data)
	}
	close(data)
	gx.Wait()
	return
}

func read(s []string, data chan<- models.RunSql) {
	var gx sync.WaitGroup
	gx.Add(len(s))
	for _, v := range s {
		go Read(&gx, v, data)
	}
	gx.Wait()
}

func Read(gx *sync.WaitGroup, ph string, data chan<- models.RunSql) {
	defer gx.Done()
	// 打开文件
	file, err := os.Open(ph)
	if err != nil {
		panic(fmt.Sprintf("%s-%v", "打开文件失败:", err))
		return
	}
	defer file.Close()

	// 创建一个 Scanner 来读取文件内容
	scanner := bufio.NewScanner(file)
	dateRegex := regexp.MustCompile(`\[\s*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2})\s*\]`)
	pattern := `SQL:\s*(.+?)\s+\[.*\]`

	// 编译正则表达式
	sqlRx := regexp.MustCompile(pattern)

	var datetime time.Time
	// 逐行读取文件内容
	for scanner.Scan() {
		// 打印每行内容
		val := scanner.Text()
		if len(val) == 0 {
			continue
		}
		match := dateRegex.FindStringSubmatch(scanner.Text())
		if len(match) > 1 {
			datetime, err = time.Parse(time.RFC3339, match[1])
			if err != nil {
				pc("解析日期时间失败:", err)
				return
			}
			fmt.Println(datetime)
		}
		matches := sqlRx.FindAllStringSubmatch(val, -1)
		// 输出匹配的 SQL 语句
		for _, match = range matches {
			if len(match) < 2 {
				continue
			}
			var m models.RunSql
			m.Sql = match[1]
			m.RunTime = datetime
			firstWord := strings.Fields(m.Sql)
			if len(firstWord) > 0 {
				m.Feature = firstWord[0]
			}
			data <- m
		}
	}

	// 检查是否出现扫描错误
	if err = scanner.Err(); err != nil {
		pc("读取文件失败:", err)
	}
	return
}

func insert(gx *sync.WaitGroup, data <-chan models.RunSql) {
	defer gx.Done()
	for v := range data {
		err := v.Create()
		if err != nil {
			pc("新增", err)
			return
		}
	}
}

func pc(s string, err error) {
	panic(fmt.Sprintf("%s-%v", s, err))
}
